#include "common_opr_all.h"
#include <algorithm>
#include <stdlib.h>

CommonOprString::CommonOprString()
{
}

CommonOprString::~CommonOprString()
{
}

std::string CommonOprString::stringReplace(const std::string &source, const std::string &oldValue, const std::string &newValue)
{
    std::string str = source;
    for (std::string::size_type pos(0); pos != std::string::npos; pos += newValue.length())
    {
        if ((pos = str.find(oldValue, pos)) != std::string::npos)
        {
            str.replace(pos, oldValue.length(), newValue);
        }
        else
        {
            break;
        }
    }

    return str;
}

vector<string> CommonOprString::splitbypattern(const string &strIn, const string &pattern)
{
    vector<string> res;
    if ("" == strIn)
    {
        return res;
    }

    //在字符串末尾也加入分隔符，方便截取最后一段
    string strs = strIn + pattern;
    size_t pos = strs.find(pattern);

    while (pos != strs.npos)
    {
        string temp = strs.substr(0, pos);
        res.push_back(temp);
        //去掉已分割的字符串,在剩下的字符串中进行分割
        strs = strs.substr(pos + pattern.size(), strs.size());
        pos = strs.find(pattern);
    }

    return res;
}

void CommonOprString::strchangelower(string &strInAndOut)
{
    for (int i = 0; i < strInAndOut.size(); i++)
    {
        if (strInAndOut[i] >= 'A' && strInAndOut[i] <= 'Z')
        {
            strInAndOut[i] = strInAndOut[i] + 32;
        }
    }
}

void CommonOprString::strchangeupper(string &strInAndOut)
{
    for (int i = 0; i < strInAndOut.size(); i++)
    {
        if (strInAndOut[i] >= 'a' && strInAndOut[i] <= 'z')
        {
            strInAndOut[i] = strInAndOut[i] - 32;
        }
    }
}

int CommonOprString::bytesToHexStr(const uint8_t *input_Bytes, uint32_t BytesLen, string &strOut)
{

    if (NULL == input_Bytes || BytesLen == 0)
    {
        return -1;
    }

    char *pTempBuf = (char *)malloc(BytesLen * 2 + 1);
    if (NULL == pTempBuf)
    {
        return -2;
    }
    memset(pTempBuf, 0, BytesLen * 2 + 1);

    for (uint32_t i = 0; i < BytesLen; i++)
    {
        sprintf(&pTempBuf[i * 2], "%02X", input_Bytes[i]);
    }

    pTempBuf[BytesLen * 2] = '\0';

    strOut = string(pTempBuf);

    // Log_Info("[CommonOprString] [bytesToHexStr] strOut: {}", strOut);

    free(pTempBuf);
    pTempBuf = NULL;
    return 0;
}

int CommonOprString::bytesToHexStrLower(const uint8_t *input_Bytes, uint32_t BytesLen, string &strOut)
{
    if (NULL == input_Bytes || BytesLen == 0)
    {
        return -1;
    }

    char *pTempBuf = (char *)malloc(BytesLen * 2 + 1);
    if (NULL == pTempBuf)
    {
        return -2;
    }
    memset(pTempBuf, 0, BytesLen * 2 + 1);

    for (uint32_t i = 0; i < BytesLen; i++)
    {
        sprintf(&pTempBuf[i * 2], "%02x", input_Bytes[i]);
    }

    pTempBuf[BytesLen * 2] = '\0';

    strOut = string(pTempBuf);

    // Log_Info("[CommonOprString] [bytesToHexStr] strOut: {}", strOut);

    free(pTempBuf);
    pTempBuf = NULL;
    return 0;
}

string CommonOprString::GetRandStr(const int strlen)
{
    // 产生随机种子  把0换成NULL也行
    srand((int)time(0));
    std::string temp;
    for (int i = 0; i < strlen; i++)
    {
        switch (rand() % 3)
        {
        case 0:
            temp += rand() % 10 + '0';
            break;

        case 1:
            temp += rand() % 26 + 'a';
            break;

        case 2:
            temp += rand() % 26 + 'A';
            break;
        }
    }
    return temp;
}

string CommonOprString::getbetweenstrs(const string &str, const string &start, const string &end)
{
    string res = "";
    if (str == "")
    {
        return res;
    }

    size_t pos_start = str.find(start);
    size_t pos_end = str.find(end);

    if (pos_start == str.npos && pos_end == str.npos)
    {
        return res;
    }

    if (pos_start == str.npos)
    {
        pos_start = 0;
    }
    else
    {
        pos_start = pos_start + start.size();
    }

    if (pos_end == str.npos)
    {
        pos_end = str.size();
    }

    if (pos_start < pos_end)
    {
        res = str.substr(pos_start, pos_end);
    }

    return res;
}

string CommonOprString::hex_to_asciistring(const uint8_t *data, uint32_t size, string &str)
{
    string strOut;
    bytesToHexStr(data, size, strOut);
    str += strOut;
    return strOut;
}

string CommonOprString::hex_to_asciistring_uint8_t(const uint8_t data, string &str)
{

    uint8_t deposit[1];

    deposit[0] = data;

    string strOut;
    bytesToHexStr(deposit, 1, strOut);
    str += strOut;
    return strOut;
}

string CommonOprString::hex_to_asciistring_uint16_t(const uint16_t data, string &str)
{
    uint8_t deposit[2];

    auto store = data / (1 << 8);
    auto remain = data % (1 << 8);

    deposit[0] = (uint8_t)store;
    deposit[1] = (uint8_t)remain;

    string strOut;
    bytesToHexStr(deposit, 2, strOut);
    str += strOut;
    return strOut;
}

string CommonOprString::hex_to_asciistring_uint32_t(const uint32_t data, string &str)
{
    uint8_t deposit[4];

    auto store = data / (1 << 24);
    auto remain = data % (1 << 24);
    deposit[0] = (uint8_t)store;

    store = remain / (1 << 16);
    remain = remain % (1 << 16);
    deposit[1] = (uint8_t)store;

    store = remain / (1 << 8);
    remain = remain % (1 << 8);
    deposit[2] = (uint8_t)store;
    deposit[3] = (uint8_t)remain;

    string strOut;
    bytesToHexStr(deposit, 4, strOut);
    str += strOut;
    return strOut;
}

int CommonOprString::childStrContainCheck(const string &checkedStr, const string &childStr)
{
    size_t pos = checkedStr.find(childStr);

    while (pos != checkedStr.npos)
    {
        return DC_SUCC;
    }
    return DC_FAIL;
}
//删除字符串中的换号（\n）
void CommonOprString::deletEnter(string &strInAndOut)
{
    strInAndOut.erase(remove(strInAndOut.begin(),strInAndOut.end(),'\n'),strInAndOut.end());
}

int CommonOprString::suffixStrContainCheck(const string &checkedStr, const string &suffix)
{
    size_t pos = checkedStr.rfind(suffix);
    if (pos != std::string::npos)
    {
        std::string extension = checkedStr.substr(pos);
        return suffix == extension;
    }
    return 0;
}

int CommonOprString::prefixStrContainCheck(const string &checkedStr, const string &prefix)
{
    size_t pos = checkedStr.find(prefix);
    if (pos == 0)
    {
        
        return 1;
    }
    return 0;
}
